# 请设计一个卷积神经网络(CNN)。
# 1.
# 该网络执行如下操作：
#
# - 第一层： 使用96个大小为11×11、步长为4、填充为2的卷积核，将输入3×224×224
# 的图像输出为96×55×55
# 的图像， 使用ReLU为激活函数;
#
# - 第二层： 大小为3×3、 步长为2、无填充的极大值池化层，将96×55×55
# 的图像输出为96×27×27;
#
# - 第三层： 使用256个大小为5×5、步长为1、填充为2的卷积核，将输入96×27×27
# 的图像输出为256×27×27
# 的图像， 使用ReLU为激活函数;
#
# - 第四层： 大小为3×3、步长为2、无填充的极大值池化层，将256×27×27
# 的图像输出为256×13×13;
#
# - 第五层： 使用384个大小为3×3、步长为1、填充为1的卷积核，将输入256×13×13
# 的图像输出为384×13×13
# 的图像， 使用ReLU为激活函数;
#
# - 第六层： 使用256个大小为3×3、步长为1、填充为1的卷积核，将输入384×13×13
# 的图像输出为256×13×13
# 的图像， 使用ReLU为激活函数;
#
# - 第七层： 大小为3×3、步长为1、填充为1的极大值池化层，将256×13×13
# 的图像输出为256×13×13;
#
# - 第八层： 将上一层的输入拉伸为行向量;
#
# - 第九层： 全连接层：将上一层拉伸后的向量变成4096维向量;
# 使用ReLU为激活函数;
#
# - 第十层： 全连接层：将上一层输出得向量变成1000维向量;


import torch
import torch.nn as nn

# 你设计的网络,网络名为net
net = nn.Sequential(
    # layer 1
    nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4, padding=2),
    nn.ReLU(),
    # layer 2
    nn.MaxPool2d(kernel_size=3, stride=2),
    # layer 3
    nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, stride=1, padding=2),
    nn.ReLU(),
    # layer 4
    nn.MaxPool2d(kernel_size=3, stride=2),
    # layer 5
    nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, stride=1, padding=1),
    nn.ReLU(),
    # layer 6
    nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, stride=1, padding=1),
    nn.ReLU(),
    # layer 7
    nn.MaxPool2d(kernel_size=3, stride=2),
    # layer 8
    nn.Flatten(),
    # layer 9
    nn.Linear(in_features=9216, out_features=4096),
    nn.ReLU(),
    # layer 10
    nn.Linear(in_features=4096, out_features=1000)
)

# 检查设计的网络net是否符合要求：
X = torch.randn(1, 3, 224, 224)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__, 'output shape: \t', X.shape)


# # 代码块的输出需与下面结果保持一致：
# """
# Conv2d output shape: 	 torch.Size([1, 96, 55, 55])
# ReLU output shape: 	 torch.Size([1, 96, 55, 55])
# MaxPool2d output shape: 	 torch.Size([1, 96, 27, 27])
# Conv2d output shape: 	 torch.Size([1, 256, 27, 27])
# ReLU output shape: 	 torch.Size([1, 256, 27, 27])
# MaxPool2d output shape: 	 torch.Size([1, 256, 13, 13])
# Conv2d output shape: 	 torch.Size([1, 384, 13, 13])
# ReLU output shape: 	 torch.Size([1, 384, 13, 13])
# Conv2d output shape: 	 torch.Size([1, 256, 13, 13])
# ReLU output shape: 	 torch.Size([1, 256, 13, 13])
# MaxPool2d output shape: 	 torch.Size([1, 256, 13, 13])
# Flatten output shape: 	 torch.Size([1, 43264])
# Linear output shape: 	 torch.Size([1, 4096])
# ReLU output shape: 	 torch.Size([1, 4096])
# Linear output shape: 	 torch.Size([1, 1000])
# """